package com.system.demo.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.system.demo.commonService.RabbitMQService;
import com.system.demo.commonService.RedisService;
import com.system.demo.entity.DTO.*;
import com.system.demo.entity.VO.CognizanceVO;
import com.system.demo.entity.database.*;
import com.system.demo.entity.excelFile.ApplicationDTO;
import com.system.demo.entity.excelFile.ApplicationDTOForExcel;
import com.system.demo.mapper.*;
import com.system.demo.service.CompetitionService;
import com.system.demo.tool.ResponseResult;
import com.system.demo.utils.ApplicationDTOMapper;
import com.system.demo.utils.ExcelExportUtil;
import com.system.demo.utils.MinioUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import static cn.hutool.core.date.DateUtil.formatLocalDateTime;
import static com.system.demo.service.constant.ApplicationStatus.*;
import static com.system.demo.service.constant.CognizanceLevelConstant.getFinalRankNameDescription;
import static com.system.demo.service.constant.CognizanceRankConstant.getFinalRankLevelDescription;
import static com.system.demo.service.constant.SubmitApplication.CompetitionMode.XIAN_SHANG;
import static com.system.demo.service.constant.SubmitApplication.ParticipantType.GE_REN;
import static com.system.demo.service.constant.UserNotificationConstant.NO_CHECK;


@Service
public class CompetitionServiceImpl implements CompetitionService {

    @Autowired
    private SubmitApplicationMapper submitApplicationMapper;

    @Autowired
    private CompetitionFileMapper competitionFileMapper;

    @Autowired
    private CognizanceMapper cognizanceMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private MinioUtils minioUtils;

    @Autowired
    private RedisService redisService;

    @Autowired
    private RabbitMQService rabbitMQService;

    @Value("${myIp.ip}")
    private String ip;



    @Value("${minio.port}")
    private int port;

    @Value("${minio.bucketName}")
    private String bucketName;

    /**
     * 学科竞赛申报审核：
     *
     * @param submitApplicationInfo 前端提交的竞赛申请表单
     * @return 返回信息
     */
    @Override
    public ResponseResult<?> submitApplication(SubmitApplicationInfo submitApplicationInfo) {
        String uid = StpUtil.getLoginId().toString();

        // 判断传来的 Info 内部是否没有数据或者数据不全
        if (isSubmitApplicationInfoInvalid(submitApplicationInfo)) {
            return ResponseResult.BadRequest("提交的申请信息不完整，请检查后再提交");
        }
        if(submitApplicationInfo.getParticipationMode() == 0){
            submitApplicationInfo.setCompetitionPosition(null);
        }
        if(submitApplicationInfo.getParticipantType() == 0){
            submitApplicationInfo.setTeamRank(0);
            submitApplicationInfo.setTeamMembers(null);
        }

        String lockKey = "lock:submitApplication:" + uid;
        long lockExpireTime = 10; // 锁的过期时间（秒）

        return redisService.executeWithLock(lockKey, lockExpireTime, () -> {
            // 查询学生信息
            Student student = getStudentInfo(uid);
            if (student == null) {
                return ResponseResult.BadRequest("用户信息不存在，无法提交申请");
            }

            // 构建申请对象
            SubmitApplication submitApplication = buildSubmitApplication(submitApplicationInfo, uid, student);

            // 插入提交记录到数据库
            if (submitApplicationMapper.insert(submitApplication) > 0) {
                return ResponseResult.success("上传竞赛申请成功");
            }
            return ResponseResult.InternalServerError("数据库连接失败,请重试");
        });
    }

    // 检查提交的申请信息是否完整
    private boolean isSubmitApplicationInfoInvalid(SubmitApplicationInfo submitApplicationInfo) {
        if (submitApplicationInfo == null) {
            return true;
        }

        // 必填字段检查
        return isEmpty(submitApplicationInfo.getCompetitionName()) ||
                isEmpty(submitApplicationInfo.getCompetitionTutor()) ||
                isEmpty(submitApplicationInfo.getCompetitionTime()) ||
                submitApplicationInfo.getParticipationMode() == null ||
                submitApplicationInfo.getParticipantType() == null;
    }
    // 判断字符串是否为空或null
    private boolean isEmpty(String str) {
        return str == null || str.trim().isEmpty();
    }


    /**
     * 查询学科竞赛所有申请表：
     * @param searchDTO 查询条件
     * @return 返回信息
     */
    @Override
    public ResponseResult<?> searchAllCompetitionApplications(ApplicationSearchDTO searchDTO, int current, int size) {

        // 处理空字符串
        if (searchDTO.getUid() != null && searchDTO.getUid().isEmpty()) {
            searchDTO.setUid(null);
        }
        if (searchDTO.getName() != null && searchDTO.getName().isEmpty()) {
            searchDTO.setName(null);
        }

        if(searchDTO.getAppClass()!=null && searchDTO.getAppClass().isEmpty()){
            searchDTO.setAppClass(null);
        }

        if (searchDTO.getCompetitionName() != null && searchDTO.getCompetitionName().isEmpty()) {
            searchDTO.setCompetitionName(null);
        }
        if (searchDTO.getStartTime() != null && searchDTO.getStartTime().isEmpty()) {
            searchDTO.setStartTime(null);
        }
        if (searchDTO.getEndTime() != null && searchDTO.getEndTime().isEmpty()) {
            searchDTO.setEndTime(null);
        }

        LambdaQueryWrapper<SubmitApplication> queryWrapper = new LambdaQueryWrapper<>();

        if (searchDTO.getStatus() != null) {
            queryWrapper.eq(SubmitApplication::getStatus, searchDTO.getStatus());
        }

        if (searchDTO.getStartTime() != null) {
            queryWrapper.ge(SubmitApplication::getCompetitionTime, searchDTO.getStartTime());
        }

        if (searchDTO.getEndTime() != null) {
            queryWrapper.le(SubmitApplication::getCompetitionTime, searchDTO.getEndTime());
        }

        if (searchDTO.getUid() != null) {
            queryWrapper.like(SubmitApplication::getUid, searchDTO.getUid());
        }

        if (searchDTO.getName() != null) {
            queryWrapper.like(SubmitApplication::getName, searchDTO.getName());
        }

        if(searchDTO.getAppClass() != null){
            queryWrapper.like(SubmitApplication::getStudentClass, searchDTO.getAppClass());
        }

        if (searchDTO.getCompetitionName() != null) {
            queryWrapper.like(SubmitApplication::getCompetitionName, searchDTO.getCompetitionName());
        }

        // 分页参数
        Page<SubmitApplication> page = new Page<>(current, size);

        // 执行查询
        Page<SubmitApplication> results = submitApplicationMapper.selectPage(page, queryWrapper);

        return ResponseResult.success("筛选成功",results.getTotal(),results.getRecords());

    }

    /**
     * 学科竞赛申报审核：
     * @param applicationIds 处理申请的id:String
     * @return 返回信息
     */
    @Override
    public ResponseResult<?> reviewApplication(ApplicationIdDTO applicationIds, Integer isPass) {
        try {
            // 验证 isPass 参数是否合法
            if (isPass == null || (isPass != 1 && isPass != 0)) {
                return ResponseResult.BadRequest("无效的审核操作");
            }

            List<Integer> ids = applicationIds.getApplicationId();
            if (ids.isEmpty()) {
                return ResponseResult.BadRequest("传入list为空，请先选中");
            }
            // 获取所有提交的申请
            List<SubmitApplication> applications = submitApplicationMapper.selectBatchIds(ids);
            if (applications.isEmpty()) {
                return ResponseResult.NotFound("未查询到对应的记录");
            }

            // 查找状态不为 'SUBMITTED' 的申请ID
            List<Integer> invalidStatusIds = applications.stream()
                    .filter(app -> app.getStatus() != SUBMITTED) // 过滤出非 SUBMITTED 状态的申请
                    .map(SubmitApplication::getId)
                    .collect(Collectors.toList());

            if (!invalidStatusIds.isEmpty()) {
                // 如果存在非 SUBMITTED 状态的申请，返回异常提示
                String message = "以下申请的状态不是 '提交' 状态，无法审核: " +
                        String.join(", ", invalidStatusIds.stream().map(String::valueOf).toArray(String[]::new));
                return ResponseResult.BadRequest(message);
            }

            // 更新状态
            int updateCount;
            if (isPass == APPROVED) {
                updateCount = submitApplicationMapper.batchUpdateStatus(ids, APPROVED);
            } else {
                updateCount = submitApplicationMapper.batchUpdateStatus(ids, REJECTED);
            }

            // 在审核逻辑完成之后
            if (updateCount > 0) {
                // 构造不同的成功或失败消息
                String messageHead = isPass == 1 ? "审核通过啦！" : "很遗憾";
                String messageResult = isPass == 1 ? "审核已通过,请尽快上传认定材料" : "审核未通过，请联系辅导员";
                // 循环处理每个申请并发送通知
                for (SubmitApplication application : applications) {
                    // 创建一个 UserNotifications 实体对象
                    String messageBody = "您的关于《" +application.getCompetitionName()+"》竞赛申请，";
                    String successMessage = messageHead + messageBody + messageResult;
                    UserNotifications notification = new UserNotifications();
                    notification.setUid(application.getUid()); // 获取对应的用户 ID
                    notification.setContent(successMessage);
                    notification.setStatus(NO_CHECK); // 1表示已阅，0表示未读
                    notification.setCreatedTime(LocalDateTime.now()); // 设置当前时间

                    // 发送消息到 RabbitMQ
                    rabbitMQService.sendNotification(notification);
                }

                return ResponseResult.success("审核完成");
            } else {
                return ResponseResult.InternalServerError("服务器内部错误，审核失败");
            }

        } catch (NumberFormatException e) {
            return ResponseResult.BadRequest("无效的申请ID");
        } catch (Exception e) {
            return ResponseResult.InternalServerError("审核过程中发生错误: " + e.getMessage());
        }
    }



    /**
     * 学生查看自己提交过的所有申请：
     *
     * @return 返回信息
     */
    @Override
    public ResponseResult<?> getReviewResult() {
        LambdaQueryWrapper<SubmitApplication> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SubmitApplication::getUid, StpUtil.getLoginId().toString());
        //因为考虑到数据量的问题，就没有做分页，感觉没必要
        //拿到相应的申请数据
        List<SubmitApplication> submitApplications = submitApplicationMapper.selectList(wrapper);

        return ResponseResult.success("查看成功",submitApplications);
    }

    /**
     * 学生提交竞赛证书 并上传竞赛名称：
     *
     * @param applicationId 对应的申请号
     * @param file 证书
     * @param rewardTitle 奖励全称
     * @return 返回信息
     */
    @Override
    @Transactional
    public ResponseResult<?> uploadFile(Integer applicationId, MultipartFile file, String rewardTitle, LocalDateTime awardDate) {
        try {
            // 查询提交申请信息
            LambdaQueryWrapper<SubmitApplication> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(SubmitApplication::getId, applicationId);
            SubmitApplication submitApplication1 = submitApplicationMapper.selectOne(wrapper1);

            // 权限验证：检查是否是当前用户的申请
            if (submitApplication1 == null || !submitApplication1.getUid().equals(StpUtil.getLoginId().toString())) {
                return ResponseResult.Forbidden("当前applicationId无效 or 您正在处理不属于您自己的申请");
            }

            // 状态验证：检查是否可以上传文件
            if (submitApplication1.getStatus() != APPROVED &&
                    submitApplication1.getStatus() != SUBMITTED_RECOGNITION_REQUEST &&
                    submitApplication1.getStatus() != REJECTED_RECOGNITION_REQUEST) {
                return ResponseResult.Forbidden("您正在试图修改一个非法的申请状态，你想干嘛");
            }

            // 处理文件上传
            String originalFilename = file.getOriginalFilename();
            String fileExtension = null;
            if (originalFilename != null && originalFilename.contains(".")) {
                fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            String stuId = StpUtil.getLoginId().toString();
            //拼接文件名 防止同名造成数据异常  示例：罗登-美国大学生数学建模竞赛M奖-15  （后面15是当前申请的id 保证唯一性）
            String objectName = submitApplication1.getName()+"-"+rewardTitle+"-"+applicationId.toString() + fileExtension;
            String path = stuId + "/" + MINIO_COMPETITION_PATH;

            // 查询并删除已有的文件记录
            LambdaQueryWrapper<CompetitionFile> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CompetitionFile::getApplicationId, applicationId);
            CompetitionFile oldFile = competitionFileMapper.selectOne(wrapper);
            if (oldFile != null) {
                // 删除旧文件
                String oldObjectName = oldFile.getFileUrl().substring(oldFile.getFileUrl().lastIndexOf("/") + 1);
                String bucketPath = stuId + "/" + MINIO_COMPETITION_PATH + "/" + oldObjectName;
                boolean deleteSuccess = minioUtils.deleteFile(bucketName, bucketPath);
                if (!deleteSuccess) {
                    return ResponseResult.InternalServerError("Minio错误，删除旧文件失败");
                }

                // 删除数据库中的旧记录
                competitionFileMapper.deleteById(oldFile.getId());
            }

            // 上传新文件到 Minio
            boolean uploadSuccess = minioUtils.uploadFile(file, bucketName, path, objectName);
            if (!uploadSuccess) {
                return ResponseResult.InternalServerError("Minio错误，文件上传失败");
            }

            // 生成文件的完整 URL
            String fileUrl = "http://" + ip + ":" + port + "/" + bucketName + "/" + path + "/" + objectName;

            // 保存新文件信息到数据库
            CompetitionFile competitionFile = new CompetitionFile();
            competitionFile.setApplicationId(applicationId);
            competitionFile.setFileUrl(fileUrl);
            competitionFile.setRewardTitle(rewardTitle);
            competitionFile.setCreateTime(LocalDateTime.now());
            competitionFile.setRewardTime(awardDate);
            if (!(competitionFileMapper.insert(competitionFile) > 0)) {
                return ResponseResult.InternalServerError("服务器内部错误，文件信息保存失败");
            }

            // 更新提交申请的状态
            SubmitApplication submitApplication = new SubmitApplication();
            submitApplication.setId(applicationId);
            submitApplication.setStatus(SUBMITTED_RECOGNITION_REQUEST);
            if (!(submitApplicationMapper.updateById(submitApplication) > 0)) {
                throw new RuntimeException("更新申请状态失败");
            }

            return ResponseResult.success("文件上传成功");

        } catch (Exception e) {
            return ResponseResult.InternalServerError("服务器内部错误: " + e.getMessage());
        }
    }


    /**
     * 学生提交竞赛证书 并上传竞赛名称：
     *
     * @param applicationId 对应的申请号
     * @param finalRankName 认定的竞赛等级
     * @param finalRankLevel 认定的竞赛级别
     * @return 返回信息
     */
    @Override
    @Transactional
    public ResponseResult<?> cognizance(Integer applicationId, Integer isPass, Integer finalRankName, Integer finalRankLevel) {
        // 查询申请记录
        SubmitApplication submitApplication = submitApplicationMapper.selectOne(
                new QueryWrapper<SubmitApplication>().in("id", applicationId));
        if (submitApplication == null) {
            return ResponseResult.BadRequest("无此申请，请检查");
        }

        // 检查申请状态
        if (submitApplication.getStatus() != SUBMITTED_RECOGNITION_REQUEST) {
            return ResponseResult.BadRequest("该申请已被认定或不可被认定");
        }

        try {
            if (isPass == 0) {
                // 驳回申请
                submitApplicationMapper.updateStatusById(
                        applicationId, REJECTED_RECOGNITION_REQUEST);

                // 发布驳回通知
                String message = submitApplication.getName() + "同学，您的关于：《"
                        + submitApplication.getCompetitionName() + "》" +
                        "的认定申请已被管理员驳回，请检查您填写的获奖全称、获奖时间是否与证书匹配，并及时前往系统重新上传证明材料。";

                UserNotifications notification = new UserNotifications();
                notification.setUid(submitApplication.getUid());
                notification.setContent(message);
                notification.setStatus(NO_CHECK);
                notification.setCreatedTime(LocalDateTime.now());

                rabbitMQService.sendNotification(notification);
                return ResponseResult.success("已驳回认定申请，通知已发送");

            } else if (isPass == 1) {
                // 通过认定
                Cognizance cognizance = new Cognizance();
                cognizance.setFinalRankLevel(finalRankLevel);
                cognizance.setFinalRankName(finalRankName);
                cognizance.setApplicationId(applicationId);
                cognizance.setCreateTime(LocalDateTime.now());

                if (cognizanceMapper.insert(cognizance) <= 0) {
                    return ResponseResult.InternalServerError("服务器内部错误，认定失败");
                }

                // 更新申请状态
                SubmitApplication newSubmitApplication = new SubmitApplication();
                newSubmitApplication.setId(applicationId);
                newSubmitApplication.setStatus(APPROVED_RECOGNITION_REQUEST);

                if (submitApplicationMapper.updateById(newSubmitApplication) <= 0) {
                    throw new RuntimeException("更新申请状态失败");
                }

                // 发布通过通知
                String message = submitApplication.getName() + "同学，您的关于：《"
                        + submitApplication.getCompetitionName() + "》" +
                        "的认定申请已通过，您可以查看系统记录。";

                UserNotifications notification = new UserNotifications();
                notification.setUid(submitApplication.getUid());
                notification.setContent(message);
                notification.setStatus(NO_CHECK);
                notification.setCreatedTime(LocalDateTime.now());

                rabbitMQService.sendNotification(notification);
                return ResponseResult.success("认定成功，通知已发送");

            } else {
                // 非法 isPass 值
                return ResponseResult.BadRequest("isPass 无法被解析，请重试");
            }
        } catch (Exception e) {
            return ResponseResult.InternalServerError("服务器内部错误：" + e.getMessage());
        }
    }



    @Override
    public void exportApplicationExcel(ApplicationSearchDTO applicationSearchDTO, HttpServletResponse response) {
        // 获取数据
        List<ApplicationDTO> lists = submitApplicationMapper.getCombinedApplicationData(applicationSearchDTO);

        // 转换为新的DTO
        List<ApplicationDTOForExcel> excelLists = lists.stream()
                .map(ApplicationDTOMapper::mapToExcelDTO)
                .collect(Collectors.toList());

        // 使用通用的排序方法，减少重复代码
        List<ApplicationDTOForExcel> sortedLists = sortApplicationData(excelLists);

        // 为 sortedLists 添加顺序 id
        for (int i = 0; i < sortedLists.size(); i++) {
            sortedLists.get(i).setId(i + 1); // 假设 ID 是 Long 类型
        }

        // 将数据导出到 Excel
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            ExcelExportUtil.exportToExcel(sortedLists, baos);
            baos.flush();
            byte[] bytes = baos.toByteArray();

            // 设置响应
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=competitions.xlsx");
            response.setContentLength(bytes.length);

            try (OutputStream os = response.getOutputStream(); InputStream is = new ByteArrayInputStream(bytes)) {
                byte[] buffer = new byte[1024];
                int len;
                while ((len = is.read(buffer)) != -1) {
                    os.write(buffer, 0, len);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("Failed to export Excel file", e);
        }
    }
    // 提取排序逻辑为一个方法，避免重复代码
    //未之后的excel表中排序
    private List<ApplicationDTOForExcel> sortApplicationData(List<ApplicationDTOForExcel> excelLists) {
        return excelLists.stream()
                .sorted(Comparator.comparing(ApplicationDTOForExcel::getCognizanceCreateTime, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getFinalRankLevel, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getFinalRankName, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getFileCreateTime, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getRewardTitle, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getFileUrl, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getApplicationCreateTime, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getStatus, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getTeamRank, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getTeamMembers, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getParticipantType, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getCompetitionPosition, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getParticipationMode, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getCompetitionTime, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getCompetitionTutor, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getCompetitionName, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getUid, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getStudentClass, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getStudentName, Comparator.nullsFirst(Comparator.naturalOrder()))
                        .thenComparing(ApplicationDTOForExcel::getId, Comparator.nullsFirst(Comparator.naturalOrder())))
                .collect(Collectors.toList());
    }



    @Override
    public ResponseResult<?> noReward(Integer applicationId) {
        SubmitApplication submitApplication = submitApplicationMapper.selectOne(new QueryWrapper<SubmitApplication>()
                .in("id", applicationId));
        if(!submitApplication.getUid().equals(StpUtil.getLoginId().toString())){
            return ResponseResult.Unauthorized("试图修改未授权的系统数据");
        }
        submitApplication.setStatus(COMPLETED);
        if(!(submitApplicationMapper.updateById(submitApplication) > 0)){
            return ResponseResult.InternalServerError("提交信息失败，请重试");
        }
        return  ResponseResult.success("同学请继续加油！祝你下次取得好成绩！");
    }

    @Override
    public ResponseResult<?> deleteFile(Integer applicationId) {
        try {
            SubmitApplication application = submitApplicationMapper.findByApplicationId(applicationId);
            String Uid = StpUtil.getLoginId().toString();
            if (!Uid.equals(application.getUid())) {
                return ResponseResult.Forbidden("你又想干嘛？");
            }
            if (application.getStatus() != 0){
                return ResponseResult.Forbidden("已经审批完成，无法修改");
            }
            submitApplicationMapper.deleteById(applicationId,Uid);
            return ResponseResult.success("Application deleted successfully.");
        } catch (Exception e) {
            // 记录异常信息，可以使用日志框架如Log4j或SLF4J
            return ResponseResult.InternalServerError("Failed to delete competition: " + e.getMessage());
        }
    }

    //根据applicationId查找详细信息，特别是认定的时候，我需要查看提交的证明 等等
    @Override
    public ResponseResult<?> getCognizanceInfo(Integer applicationId) {
        CompetitionFile competitionFile = competitionFileMapper.selectOne(new QueryWrapper<CompetitionFile>()
                .in("application_id", applicationId));
        if(competitionFile == null){
            return ResponseResult.BadRequest("该用户未提交证明或提交记录被删除");
        }

        return ResponseResult.success("获取详情成功", competitionFile);
    }

    @Override
    @Transactional
    public ResponseResult<?> cognizanceCheck(Integer applicationId, Integer isPass, Integer finalRankName, Integer finalRankLevel) {
        // 检查申请记录
        SubmitApplication submitApplication = submitApplicationMapper.selectOne(
                new QueryWrapper<SubmitApplication>().in("id", applicationId));
        if (submitApplication == null) {
            return ResponseResult.BadRequest("无此申请，请检查");
        }

        // 校验 isPass 参数
        int isPassValue;
        try {
            isPassValue = isPass;
        } catch (NumberFormatException e) {
            return ResponseResult.BadRequest("isPass 无法被解析，请重试");
        }

        // 根据 isPass 值处理逻辑
        if (isPassValue == 0) {
            // 驳回认定申请
            submitApplicationMapper.updateStatusById(
                    applicationId, REJECTED_RECOGNITION_REQUEST);

            // 删除认定表中的记录
            int deleteCount = cognizanceMapper.delete(
                    new QueryWrapper<Cognizance>().in("application_id", applicationId));
            if (deleteCount <= 0) {
                return ResponseResult.InternalServerError("服务器内部问题，请稍后重试");
            }

            // 直接构建邮件内容并发送
            String message = submitApplication.getName() + "同学，您的关于：《"
                    + submitApplication.getCompetitionName() + "》" +"的认定申请已被管理员驳回，请及时前往系统重新上传证明材料。";


            UserNotifications notification = new UserNotifications();
            notification.setUid(submitApplication.getUid());
            notification.setContent(message);
            notification.setStatus(NO_CHECK);
            notification.setCreatedTime(LocalDateTime.now());

            rabbitMQService.sendNotification(notification);
            return ResponseResult.success("已打回认定申请");

        } else if (isPassValue == 1) {
            try {
                // 更新认定表中的记录
                Cognizance cognizance = cognizanceMapper.selectOne(
                        new QueryWrapper<Cognizance>().in("application_id", applicationId));
                if (cognizance == null) {
                    return ResponseResult.BadRequest("该申请无认定记录，无法修改");
                }

                cognizance.setFinalRankLevel(finalRankLevel);
                cognizance.setFinalRankName(finalRankName);
                cognizance.setCreateTime(LocalDateTime.now());

                if (cognizanceMapper.updateById(cognizance) <= 0) {
                    return ResponseResult.InternalServerError("服务器内部问题，请稍后重新认定");
                }

                // 直接构建邮件内容并发送
                String message = submitApplication.getName() + "同学，您的关于：《"
                        + submitApplication.getCompetitionName() + "》的认定申请已更新，请登录系统查看最终认定结果。";

                UserNotifications notification = new UserNotifications();
                notification.setUid(submitApplication.getUid());
                notification.setContent(message);
                notification.setStatus(NO_CHECK);
                notification.setCreatedTime(LocalDateTime.now());

                rabbitMQService.sendNotification(notification);

                return ResponseResult.success("认定成功");
            } catch (Exception e) {
                return ResponseResult.InternalServerError("服务器内部错误：" + e.getMessage());
            }
        } else {
            // 非法 isPass 值
            return ResponseResult.BadRequest("isPass 无法被解析，请重试");
        }
    }

    @Override
    public ResponseResult<?> getUploadFile(Integer applicationId) {
        //根据申请id获取上传认定材料的信息
        SubmitApplication submitApplication = submitApplicationMapper.selectById(applicationId);
        if(submitApplication == null){
            return ResponseResult.BadRequest("该申请已被删除");
        }

        //先查看该id是否为登录本人
        if(!submitApplication.getUid().equals(StpUtil.getLoginId().toString())){
            return ResponseResult.Unauthorized("您正在试图访问他人的申请");
        }

        CompetitionFile competitionFile = competitionFileMapper.selectOne(new QueryWrapper<CompetitionFile>()
                .in("application_id", applicationId));
        if(competitionFile == null){
            return ResponseResult.InternalServerError("内部服务器错误，请重试");
        }
        //然后再返回competitionFile信息
        return ResponseResult.success("成功查询到提交的认定信息", competitionFile);
    }

    @Override
    public ResponseResult<?> modifiedApplication(SubmitApplication submitApplication) {
        //在审核之前可以进行修改
        SubmitApplication oldApplication = submitApplicationMapper.selectById(submitApplication.getId());
        if(oldApplication == null){
            return ResponseResult.BadRequest("你要修改的申请不存在，请重试");
        }
        if(!oldApplication.getUid().equals(StpUtil.getLoginId().toString())){
            return ResponseResult.Unauthorized("您试图修改他人的申请信息");
        }
        if(oldApplication.getStatus() != SUBMITTED){
            return ResponseResult.Unauthorized("申请已被审核，无法修改");
        }

        if(Objects.equals(submitApplication.getParticipationMode(), XIAN_SHANG)){
            submitApplication.setCompetitionPosition(null);
        }
        if(Objects.equals(submitApplication.getParticipantType(), GE_REN)){
            submitApplication.setTeamMembers(null);
            submitApplication.setTeamRank(null);
        }

        if(!(submitApplicationMapper.updateById(submitApplication) > 0)){
            return ResponseResult.InternalServerError("服务器内部错误,请重试");
        }
        return ResponseResult.success("修改成功");
    }

    @Override
    public ResponseResult<?> getCognizanceResult(Integer applicationId) {
        //获取认定结果
        SubmitApplication submitApplication = submitApplicationMapper.selectById(applicationId);
        if(submitApplication == null){
            return ResponseResult.BadRequest("该申请已被删除");
        }
        //首先判断是否为本人
        if(!Objects.equals(submitApplication.getUid(), StpUtil.getLoginId().toString())){
            return ResponseResult.Unauthorized("您无法查看他人的认定结果");
        }
        //再判断该申请id是否是状态5
        if(submitApplication.getStatus() != APPROVED_RECOGNITION_REQUEST){
            return ResponseResult.BadRequest("该申请还未被认定");
        }
        Cognizance cognizance = cognizanceMapper.selectOne(new QueryWrapper<Cognizance>()
                .in("application_id", applicationId));
        CognizanceVO cognizanceVO = new CognizanceVO();
        cognizanceVO.setFinalRankName(getFinalRankNameDescription(cognizance.getFinalRankName()));
        cognizanceVO.setFinalRankLevel(getFinalRankLevelDescription(cognizance.getFinalRankLevel()));
        cognizanceVO.setCognizanceTime(formatLocalDateTime(cognizance.getCreateTime()));

        return ResponseResult.success("获取认定结果成果",cognizanceVO);
    }

    @Override
    public void downloadCognizantFile(CognizantIdDTO cognizantIdDTO, HttpServletResponse response) {
        // 如果 CognizantIds 为空，返回 400 错误
        System.out.println(cognizantIdDTO.getCognizantIds());
        if (cognizantIdDTO.getCognizantIds() == null || cognizantIdDTO.getCognizantIds().isEmpty()) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }

        // 获取所有认定成功的文件 URL
        List<CompetitionFileDTO> files = cognizanceMapper.selectFilesUrlByApplicationIds(cognizantIdDTO.getCognizantIds());
        System.out.println(files);
        //判断找到的个数是否对应上查找的个数
        if(files.size() != cognizantIdDTO.getCognizantIds().size()){
            response.setStatus(HttpServletResponse.SC_BAD_GATEWAY);
            return;
        }
        // 存放要压缩的文件 URL 列表
        List<String> fileUrlList = new ArrayList<>();
        String title = "竞赛认定文件";

        // 遍历文件列表，准备文件 URL（去除 "public/" 部分）
        for (CompetitionFileDTO fileDTO : files) {
            String fileUrl = fileDTO.getFileUrl();
            if (fileUrl != null && !fileUrl.isEmpty()) {
                // 去除 "public/" 之前的部分
                String filePath = fileUrl.substring(fileUrl.indexOf("public/") + "public/".length());
                fileUrlList.add(filePath);
            }
        }
        System.out.println(fileUrlList);
        // 如果文件列表为空，返回 404 错误
        if (fileUrlList.isEmpty()) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        try {
            // 使用 Minio 工具类压缩文件并返回给前端
            minioUtils.ZipMultiFileToMinIO(response, bucketName, fileUrlList, title);
        } catch (IOException e) {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    public ResponseResult<?> getCognizanceResultByAdmin(Integer applicationId) {
        //admin查看你某id的认定结果
        Cognizance cognizance = cognizanceMapper.selectOne(new QueryWrapper<Cognizance>()
                .in("application_id", applicationId));
        if(cognizance == null){
            return ResponseResult.BadRequest("未找到该申请的认定结果");
        }
        CognizanceVO cognizanceVO = new CognizanceVO();
        cognizanceVO.setFinalRankName(getFinalRankNameDescription(cognizance.getFinalRankName()));
        cognizanceVO.setFinalRankLevel(getFinalRankLevelDescription(cognizance.getFinalRankLevel()));
        cognizanceVO.setCognizanceTime(formatLocalDateTime(cognizance.getCreateTime()));

        return ResponseResult.success("查询成功", cognizanceVO);
    }


    /**
     * 构建 SubmitApplication 对象
     */
    private SubmitApplication buildSubmitApplication(SubmitApplicationInfo submitApplicationInfo, String uid, Student student) {
        SubmitApplication submitApplication = new SubmitApplication();
        submitApplication.setStatus(SUBMITTED);
        submitInfoToSubmitApplication(submitApplicationInfo, submitApplication);
        submitApplication.setCreateTime(LocalDateTime.now());
        submitApplication.setUid(uid);
        submitApplication.setName(student.getStudentName());
        submitApplication.setStudentClass(student.getStudentClass());
        return submitApplication;
    }

    private void submitInfoToSubmitApplication(SubmitApplicationInfo submitApplicationInfo, SubmitApplication submitApplication) {
        submitApplication.setCompetitionName(submitApplicationInfo.getCompetitionName());
        submitApplication.setCompetitionPosition(submitApplicationInfo.getCompetitionPosition());
        submitApplication.setCompetitionTutor(submitApplicationInfo.getCompetitionTutor());
        submitApplication.setCompetitionTime(submitApplicationInfo.getCompetitionTime());
        submitApplication.setParticipationMode(submitApplicationInfo.getParticipationMode());
        submitApplication.setParticipantType(submitApplicationInfo.getParticipantType());
        submitApplication.setTeamMembers(submitApplicationInfo.getTeamMembers());
        submitApplication.setTeamRank(submitApplicationInfo.getTeamRank());
    }

    /**
     * 查询学生信息
     */
    private Student getStudentInfo(String uid) {
        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Student::getUid, uid);
        return studentMapper.selectOne(wrapper);
    }
}

